package com.youdianstar.app.ui.pay

import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.core.content.ContextCompat
import com.youdianstar.app.R
import com.youdianstar.app.BR
import com.youdianstar.app.entity.CardBindReq
import com.youdianstar.app.ui.ScanActivity
import com.youdianstar.app.util.DataAppManager
import com.youdianstar.app.util.initStripe
import com.youdianstar.app.databinding.ActivityCardAddBinding
import com.youdianstar.app.common.base.BaseActivity
import com.youdianstar.app.common.ex.setThrottleListener
import com.youdianstar.app.common.network.BaseApiResultObserver
import com.youdianstar.app.common.BisType
import com.youdianstar.app.common.Extra
import com.youdianstar.app.common.util.LogUtil
import com.youdianstar.app.common.util.StrUtil

import com.stripe.android.ApiResultCallback
import com.stripe.android.PaymentConfiguration
import com.stripe.android.Stripe
import com.stripe.android.model.Token
import com.stripe.android.stripecardscan.cardscan.CardScanSheet
import com.stripe.android.stripecardscan.cardscan.CardScanSheetResult
import com.stripe.android.view.CardValidCallback
import com.youdianstar.app.common.auko.startActivity
import org.koin.androidx.viewmodel.ext.android.viewModel


/**
 * File: AddCardActivity
 * Author: 82149 Create: 2021/11/25 10:01
 * Changes (from 2021/11/25)
 * --------------------------------------------------
 * description: 添加卡页面
 * ---------------------------------------------------
 *
 */
class AddCardActivity : BaseActivity<ActivityCardAddBinding, PaymentViewModel>() {
    override fun layoutId(): Int = R.layout.activity_card_add

    override fun initVariableId(): Int = BR.viewModel

    override fun initViewModel(): PaymentViewModel {
        val model: PaymentViewModel by viewModel()
        return model
    }

    private val mHandler = Handler(Looper.myLooper()!!)
    private var stripe: Stripe? = null
    private var stripeScanSheet: CardScanSheet? = null

    override fun initViewLayout() {
        super.initViewLayout()
        mBinding.headBar.initTitle(this,
            getString(R.string.wallet_addCard),
            showInner = false
        )

        mBinding.cardInput.postalCodeEnabled = true
        mBinding.cardInput.postalCodeRequired = true
        mBinding.cardInput.setCardValidCallback(object : CardValidCallback {
            override fun onInputChanged(
                isValid: Boolean,
                invalidFields: Set<CardValidCallback.Fields>
            ) {
                mBinding.btnPay.isEnabled = isValid
            }
        })
        mBinding.cardInput.postDelayed({

            showKeyBoard(mBinding.cardInput.findFocus())
        }, 200)

        mBinding.addBoxDefault.buttonDrawable =
            ContextCompat.getDrawable(this, R.drawable.selector_box_add)
    }

    override fun initData() {
        super.initData()
        stripe = initStripe(this)
        stripeScanSheet = CardScanSheet.create(from = this,
            stripePublishableKey = PaymentConfiguration.getInstance(this).publishableKey,
            object : CardScanSheet.CardScanResultCallback {
                override fun onCardScanSheetResult(cardScanSheetResult: CardScanSheetResult) {
                    when (cardScanSheetResult) {
                        is CardScanSheetResult.Completed -> {
                            LogUtil.i("Stripe scan pan:" + cardScanSheetResult.scannedCard.pan)
                            if (cardScanSheetResult.scannedCard.pan.isNotEmpty()) {
                                mBinding.cardInput.setCardNumber(cardScanSheetResult.scannedCard.pan)
                            }
                        }

                        is CardScanSheetResult.Canceled -> {
                            LogUtil.d("Stripe scan canceled")
                        }

                        else -> {
                            LogUtil.e("Stripe scan error:$cardScanSheetResult")
                        }
                    }
                }
            })
        mBinding.ibtScan.visibility = View.VISIBLE
    }

    override fun initLiveObserver() {
        super.initLiveObserver()
        mViewModel.addResultLiveData.observe(this, object : BaseApiResultObserver<Any>(true) {
            override fun onDataResult(data: Any?) {
                super.onDataResult(data)
                dismissDialog()
                mHandler.postDelayed({
                    if (DataAppManager.instance.rentScanTag) {
                        startActivity<ScanActivity>(Extra.IT_TYPE to BisType.Scan_Rent)
                    }
                    finish()
                }, 1500)
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                dismissDialog()
                toastShow(e)
            }
        })
    }

    override fun initClickEvent() {
        mBinding.btnPay.setThrottleListener {
            checkAndBind()
        }

        mBinding.ibtScan.setThrottleListener {
            stripeScanSheet?.present()
        }
    }

    private fun checkAndBind() {
        if (null == mBinding.cardInput.cardParams) {
            return
        }
        showLoadingDialog("")
        val isSetDefault = mBinding.addBoxDefault.isChecked
        mBinding.cardInput.cardParams?.let { pas ->
            stripe?.createCardToken(pas, callback = object : ApiResultCallback<Token> {
                override fun onError(e: Exception) {
                    dismissDialog()
                    toastShow(e.message)
                }

                override fun onSuccess(result: Token) {
                    result.card?.let { card ->
                        val req = CardBindReq(
                            token = result.id,
                            bankNo = card.last4 ?: "",
                            bankExpire = StrUtil.setCardBindExp(card.expYear,card.expMonth),
                            bankName = card.brand.displayName,
                            bankType = card.funding?.name,
                            postalCode = card.addressZip,
                            defaulted = isSetDefault,
                            save = true
                        )
                        mViewModel.bindCard(req)
                    }
                }
            })
        }
    }
}